iT邦幫忙

2024 iThome 鐵人賽

DAY 10
0
JavaScript

火箭通關JS30系列 第 10

JS30-10 - Hold Shift and Check Checkboxes

  • 分享至 

  • xImage
  •  

課程目的:

image.png

這次的範例給我們的是一個list選單,而我們要實作的功能是當我們勾選了其中一個A選項,當我們壓著shift並且勾選B選項時,可以將A~B之間的選項一併勾選起來
作品實做

本次功能實作重點:

  • 前置監聽以及選取器
  • handleClick函式邏輯

前置監聽以及選取器

const checkBoxes = document.querySelectorAll('.inbox input[type="checkbox"]');

checkBoxes.forEach((checkBox) => {
  checkBox.addEventListener("click", handleClick);
});

checkBoxes 選取inbox內含有type="checkbox”的input元素
checkBox.addEventListener("click", handleClick) 監聽當click此元素時執行handleClick()

handleClick函式邏輯

let lastKey = null;
function handleClick(e) {
  if (e.shiftKey && lastKey !== null) {
    let nowCheck = checkBoxes.indexOf(this);
    checkBoxes
      .slice(Math.min(nowCheck, lastKey), Math.max(nowCheck, lastKey))
      .forEach((input) => {
        input.checked = true;
      });
  }

  if (this.checked) {
    //假這有打勾 記下input的index
    lastKey = checkBoxes.indexOf(this);
  } else {
    lastKey = null;
  }
}

if (this.checked) 當我們勾選click並且此input元素是checked的狀態,lastKey賦值checkBoxes.indexOf(this) 如果false則lastKey = null

注意!
這時候我想要確認一下我點擊有沒有成功選取於是console.log(lastKey),但卻出現了此錯誤

image.png

原來是因為 querySelectorAll 返回的是 NodeList,他是like Array卻不是Array,所以無法調用indexOf 這樣的陣列方法,所以在我們選取input的時候加上Array.from(),把nodeList轉換為陣列

const checkBoxes = Array.from(
  document.querySelectorAll('.inbox input[type="checkbox"]')
);

image.png

這樣處理過後錯誤就消除了,顯示了我勾選的input的index!

if (e.shiftKey && lastKey !== null) 當按下shift時並且我們lastKey不是空值時執行以下的動作:

nowCheck 賦值為checkBoxes.indexOf(this) ,所以我們現在會有兩個值nowCheck 以及一開始勾選的lastKey

checkBoxes.slice(Math.min(nowCheck, lastKey), Math.max(nowCheck, lastKey)) 用來選出lastKey 以及nowCheck 之間的範圍,選取完使用input.checked = true ,這樣我們就可以連續選取了/

最後重點整理 :

  • nodeList並不是Array而是likeArray 若需要調用array才有的方法需要先轉為Array

上一篇
JS30-09 - Dev Tools Domination
下一篇
JS30-11-Custom Video Player
系列文
火箭通關JS3030
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言